#ifndef __TCPSERVER_HPP__
#define __TCPSERVER_HPP__

#include <functional>
#include "Protocol.hpp"
#include "Socket.hpp"
#include <signal.h>

using Func_t = function<std::string(std::string &pakeage)>;

class TcpServer
{
public:
    TcpServer()
    {
    }
    TcpServer(const uint16_t &port, Func_t callback) : _port(port), _callback(callback)
    {
    }

    bool ServerInit()
    {
        _listensock.Socket();
        _listensock.Bind(_port);
        _listensock.Listen();

        lg(INFO, "Server initialization is successful.");
        return true;
    }

    void ServerStart()
    {
        // 处理子进程回收问题
        signal(SIGCLD, SIG_IGN);
        signal(SIGPIPE, SIG_IGN);

        while (true)
        {
            std::string clientip;
            uint16_t clientport;
            int sockfd = _listensock.Accept(clientip, clientport);
            if (sockfd < 0)
                continue; // 连接客户端失败，接着去连接下一个
            std::cout << "Connection to the host information: \n"
                      << " clientip: " << clientip << " clientport: " << clientport << std::endl;
            std::string inbuffer_stream;

            // 多进程处理任务
            if (fork() == 0) // 注意fork是一给创建子进程的函数
            {
                _listensock.Close();
                char inbuffer[1024];
                // lg(INFO, "inbuffe: %s", inbuffer);
                while (true)
                {
                    ssize_t n = read(sockfd, inbuffer, sizeof(inbuffer) - 1);
                    std::cout << "read success" << std::endl;

                    if (n > 0) // 有数据
                    {
                        inbuffer[n] = 0;
                        inbuffer_stream += inbuffer; // 第一次读取的数据可能不完整，所以这里需要+=，那么inbuffer将需要定义在外面去
                        while (true)
                        {
                            std::string info = _callback(inbuffer_stream); // 处理数据
                            if (info.empty())
                                break; // 没有接收到数据直接退出即可

                            // 查看数据
                            lg(INFO, "The received data is inbuffer: %s", inbuffer);
                            lg(INFO, "The processed data is inbuffer_stream: %s", inbuffer_stream.c_str());

                            // 读取到的可能不止一个完整的数据？可以使用while循环来进行处理 一个完整报文的大小为：inbuffer_stream.size()
                            write(sockfd, info.c_str(), info.size());
                            std::cout << "write success" << std::endl;
                        }
                    }
                    else if (n == 0)
                    {
                        lg(INFO, "not data");
                        break;
                    }
                    else
                    {
                        lg(INFO, "error");
                        break;
                    }
                }
                // 处理完之后，子进程退出
                exit(0);
            }
            close(sockfd);
        }
    }

private:
    Sock _listensock;
    uint16_t _port;
    Func_t _callback;
};

#endif

// #pragma once
// #include <functional>
// #include <string>
// #include <signal.h>
// #include "Log.hpp"
// #include "Socket.hpp"

// using func_t = std::function<std::string(std::string &package)>;

// class TcpServer
// {
// public:
//     TcpServer(uint16_t port, func_t callback) : port_(port), callback_(callback)
//     {
//     }
//     bool InitServer()
//     {
//         listensock_.Socket();
//         listensock_.Bind(port_);
//         listensock_.Listen();
//         lg(INFO, "init server .... done");
//         return true;
//     }
//     void Start()
//     {
//         signal(SIGCHLD, SIG_IGN);
//         signal(SIGPIPE, SIG_IGN);
//         while (true)
//         {
//             std::string clientip;
//             uint16_t clientport;
//             int sockfd = listensock_.Accept(clientip, clientport);
//             if (sockfd < 0)
//                 continue;
//             lg(INFO, "accept a new link, sockfd: %d, clientip: %s, clientport: %d", sockfd, clientip.c_str(), clientport);
//             // 提供服务
//             if (fork() == 0)
//             {
//                 listensock_.Close();
//                 std::string inbuffer_stream;
//                 // 数据计算
//                 while (true)
//                 {
//                     char buffer[1280];
//                     ssize_t n = read(sockfd, buffer, sizeof(buffer));
//                     if (n > 0)
//                     {
//                         buffer[n] = 0;
//                         inbuffer_stream += buffer;

//                         lg(DEBUG, "debug:\n%s", inbuffer_stream.c_str());

//                         while (true)
//                         {
//                             std::string info = callback_(inbuffer_stream);
//                             if (info.empty())
//                                 break;
//                             lg(DEBUG, "debug, response:\n%s", info.c_str());
//                             lg(DEBUG, "debug:\n%s", inbuffer_stream.c_str());
//                             write(sockfd, info.c_str(), info.size());
//                         }
//                     }
//                     else if (n == 0)
//                         break;
//                     else
//                         break;
//                 }

//                 exit(0);
//             }
//             close(sockfd);
//         }
//     }
//     ~TcpServer()
//     {
//     }

// private:
//     uint16_t port_;
//     Sock listensock_;
//     func_t callback_;
// };